package com.example.demo.web.controller;

import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.StpUtil;
import com.anji.captcha.model.common.ResponseModel;
import com.anji.captcha.model.vo.CaptchaVO;
import com.anji.captcha.service.CaptchaService;
import com.example.demo.domain.base.BaseResult;
import com.example.demo.domain.vo.LoginVO;
import com.example.demo.domain.param.TokenRefresh;
import com.example.demo.domain.param.UserLoginRequest;
import com.example.demo.exception.BizException;
import com.example.demo.exception.ErrorConstants;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import java.util.Optional;
import java.util.UUID;

/**
 * AuthController
 *
 * @author haochen78
 * @date 2025/8/12 17:03
 **/
@RestController
@RequestMapping("/auth")
public class AuthController {

    @Autowired
    private CaptchaService captchaService;
    @Autowired
    private UserService userService;

    /**
     * 生成验证码
     *
     * @param clientUid 客户端每次请求生成的唯一 id
     * @return secretKey，token，originalImageBase64，jigsawImageBase64
     */
    @GetMapping("/generate")
    public BaseResult<?> generateCaptcha(@NotBlank @RequestParam String clientUid) {
        // 调用组件生成验证码，返回包含图片信息和验证标识的响应
        CaptchaVO captchaVO = new CaptchaVO();
        captchaVO.setClientUid(clientUid);
        return Optional.ofNullable(captchaService.get(captchaVO)).map(resp -> resp.isSuccess() ? BaseResult.success((CaptchaVO) resp.getRepData()) : BaseResult.failure(resp.getRepMsg())).orElseGet(() -> BaseResult.failure("响应模型为空"));
    }

    /**
     * 验证用户提交的验证码
     *
     * @param captchaVO pointJson，token，clientUid，ts
     * @return token
     */
    @PostMapping("/verify")
    public BaseResult<?> verifyCaptcha(@RequestBody CaptchaVO captchaVO) {
        // 传入用户提交的验证参数（如滑块位置、点选坐标等）
        return Optional.ofNullable(captchaService.check(captchaVO)).map(resp -> resp.isSuccess() ? BaseResult.success((CaptchaVO) resp.getRepData()) : BaseResult.failure(resp.getRepMsg())).orElseGet(() -> BaseResult.failure("响应模型为空"));
    }

    @PostMapping("/refresh")
    public BaseResult<LoginVO> refresh(@Valid @RequestBody TokenRefresh request) {
        SaSession session = StpUtil.getSession();
        String refresh = (String) session.get("refreshToken");
        if (!request.getRefreshToken().equals(refresh)) {
            throw new BizException(ErrorConstants.CLIENT_TOKEN_INVALID);
        }
        StpUtil.login(123);
        String accessToken = StpUtil.getTokenValue();
        // 生成刷新Token（存入会话，设置独立有效期）
        String refreshToken = UUID.randomUUID().toString();
        session = StpUtil.getSession();
        session.set("refreshToken", refreshToken);
        long timeMillis = System.currentTimeMillis() + 30 * 60 * 1000;
        session.set("tokenExpire", timeMillis);
        LoginVO loginVO = new LoginVO();
        loginVO.setAccessToken(accessToken);
        loginVO.setRefreshToken(refreshToken);
        loginVO.setExpireTime(timeMillis);
        return BaseResult.success(loginVO);
    }

    /**
     * 用户登录
     *
     * @param req 登录请求参数
     * @return 登录结果
     */
    @PostMapping("/login")
    public BaseResult<LoginVO> login(@RequestBody UserLoginRequest req) {
        CaptchaVO captchaVO = new CaptchaVO();
        captchaVO.setCaptchaVerification(req.getCaptchaVerification());
        ResponseModel captchaResult = captchaService.verification(captchaVO);
        if (!captchaResult.isSuccess()) {
            throw new BizException(ErrorConstants.OPERATION_FAIL, "验证码错误");
        }
        userService.login(req.getUsername(), req.getPassword());
        String accessToken = StpUtil.getTokenValue();
        // 生成刷新Token（存入会话，设置独立有效期）
        String refreshToken = UUID.randomUUID().toString();
        SaSession session = StpUtil.getSession();
        session.set("refreshToken", refreshToken);
        long timeMillis = System.currentTimeMillis() + 30 * 60 * 1000;
        session.set("tokenExpire", timeMillis);
        LoginVO loginVO = new LoginVO();
        loginVO.setAccessToken(accessToken);
        loginVO.setRefreshToken(refreshToken);
        loginVO.setExpireTime(timeMillis);
        return BaseResult.success(loginVO);
    }

    /**
     * 退出登录
     */
    @PostMapping("/logout")
    public BaseResult<Void> logout() {
        StpUtil.logout();
        return BaseResult.success();
    }
}
